# -*- coding: utf-8 -*-
'''
Created on 13 févr. 2010

@author: Plume
'''

class StructureException (Exception):
    def __init__ (self, cause=None, missing_attr=None, root_exception=None):
        super (StructureException, self).__init__(root_exception)
        self.cause = cause
        self.missing_attr = missing_attr

class ActionDescription ():
    STANDARD = 1
    GENERATOR = 2
    NOROW = 3
    def __init__ (self, factory, action_type, rows=[], inits={}):
        self.factory = factory
        self.action_type = action_type
        self.rows = rows
        self.inits = inits
        self.instances = []
    def add_instance (self, instance):
        self.instances.append (instance)

class Structure (object):
    """Encapsulates the definition of a scenario and its expected results, 
    with actual libraries and action classes,
    init parameters, expected values etc."""
    def __init__ (self):
        self.actions = []

    def add_action (self, action):
        """Appends an action in the list of actions in this Structure describing a scenario"""
        self.actions.append (action)

    def prepare (self):
        """Prepare creates the instances of actions and make sure they are properly
        defined. It checks for the action descriptions.
        """
        for s in self.actions:
            # Checking availability of minimalistic info in action descriptions
            for att in ("action_type", "factory", "inits", "rows"):
                try :
                    getattr (s, att)
                except AttributeError, ae :
                    raise StructureException (cause='Action not well defined',
                        root_exception=ae,
                        missing_attr=att)
    def run (self):
        for action in self.actions:
            if action.action_type == ActionDescription.NOROW :
                instance = action.factory ()
                action.add_instance (instance)
                if hasattr (instance, "init") :
                    d = action.inits
                    instance.init (**d)
                instance.run ()
